package com.df.dht.utils;

import com.dampcake.bencode.Bencode;
import com.dampcake.bencode.BencodeInputStream;
import com.dampcake.bencode.BencodeOutputStream;
import com.dampcake.bencode.Type;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentSkipListMap;


public class BencodeUtils {
    private static Bencode bencode = new Bencode();
    public static String encode(Map<Object, Object> map) {

        byte[] encoded = bencode.encode(map);
//        byte[] encoded = bencode.encode(new HashMap<Object, Object>() {{
//            put("string", "value");
//            put("number", 123456);
//            put("list", new ArrayList<Object>() {{
//                add("list-item-1");
//                add("list-item-2");
//            }});
//            put("dict", new ConcurrentSkipListMap() {{
//                put(123, "test");
//                put(456, "thing");
//            }});
//        }});
        return new String(encoded,bencode.getCharset());
//        System.out.println(new String(encoded, bencode.getCharset()));
    }

    public static Map<String, Object> decode(String encoded) {
        Map<String, Object> dict = bencode.decode(encoded.getBytes(), Type.DICTIONARY);
        return dict;
    }
    public static void encodeToStream(HashMap<Object, Object> data) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        BencodeOutputStream bencoder = new BencodeOutputStream(out);

        try {
            bencoder.writeDictionary(data);
        } catch (IOException e) {
            e.printStackTrace();
        }

//        System.out.println(new String(out.toByteArray()));
    }

    public static Map<String, Object> decodeFromStream(InputStream in) {

        Map<String, Object> dict = null;
        try {
            BencodeInputStream bencode = new BencodeInputStream(in);
            Type type = bencode.nextType(); // Returns Type.DICTIONARY
            dict = bencode.readDictionary();
        }catch (Exception e) {
            e.printStackTrace();
        }

        return dict;
    }
}
